import os   # 导入os模块，用于清屏操作

# 定义一个空列表，用于存储学生信息
stu = []
total = 0   # 定义一个total变量，用于存储学生人数

def set_stu():
    # 初始化一个学生字典
    student = {}
    print("请输入学生信息：")   # 输出提示信息
    while True:   # 使用无限循环，直到输入的学号不存在于stu列表中才退出循环
        number = input("学号: ")   # 输入学号
        if any(s['number'] == number for s in stu):   # 判断是否有学号与输入的学号相同的学生对象
            print("学号已存在，请重新输入。")   # 如果存在，输出提示信息
        else:   # 如果不存在，退出循环
            student['number'] = number
            break
    student['name'] = input("姓名: ")   # 输入姓名
    student['gender'] = input("性别: ")   # 输入性别
    student['age'] = int(input("年龄: "))   # 输入年龄，转换为整型
    student['stu_class'] = input("班号: ")   # 输入班号
    student['major'] = input("专业: ")   # 输入专业
    student['department'] = input("系别: ")   # 输入系别
    return student

def show_stu(s):
    # 定义一个用于显示学生信息的函数
    print(f"{s['number']:<10}{s['name']:<10}{s['gender']:<10}{s['age']:<10}{s['stu_class']:<10}{s['major']:<20}{s['department']:<20}")

def input_info():   # 定义一个名为input_info的函数，用于录入学生信息
    global total   # 声明total为全局变量
    n = int(input("请输入要录入信息的学生人数: "))   # 输入要录入信息的学生人数
    print("请依次输入学生的学号、姓名、性别、年龄、班号、专业名称、系别:")   # 输出提示信息
    for _ in range(n):   # 使用for循环，循环n次
        s = set_stu()   # 调用set_stu函数设置学生的属性
        stu.append(s)   # 将学生对象添加到stu列表中
    total += n   # 增加学生人数
    print("学生信息录入完成！")   # 输出提示信息

def delete_info():   # 定义一个名为delete_info的函数，用于删除学生信息
    global total   # 声明total为全局变量
    num = input("请输入要删除学生的学号: ")   # 输入要删除的学生的学号
    for i, s in enumerate(stu):   # 使用enumerate函数获取学生对象及其索引
        if s['number'] == num:   # 判断学号是否与输入的学号相同
            del stu[i]   # 删除对应的学生对象
            total -= 1   # 减少学生人数
            print(f"学号为 {num} 的学生信息已删除！")   # 输出提示信息
            return   # 终止函数执行
    print(f"未找到学号为 {num} 的学生，请检查学号是否输入错误！")   # 输出提示信息

def recompose_info():   # 定义一个名为recompose_info的函数，用于修改学生信息
    num = input("请输入要修改学生的原学号: ")   # 输入要修改的学生的原学号
    for s in stu:   # 遍历stu列表中的学生对象
        if s['number'] == num:   # 判断学号是否与输入的学号相同
            print("依次输入修改后的学生的学号、姓名、性别、年龄、班号、专业名称、系别:")   # 输出提示信息
            new_stu = set_stu()   # 调用set_stu函数设置学生的属性
            s.update(new_stu)  # 更新学生信息
            print(f"原学号为 {num} 的学生信息已修改！")   # 输出提示信息
            return   # 终止函数执行
    print(f"未找到学号为 {num} 的学生，请检查学号是否输入错误！")   # 输出提示信息

def find_info():   # 定义一个名为find_info的函数，用于查询学生信息
    print("=========（a）按学号查询单个学生信息")   # 输出提示信息
    print("=========（b）按姓名查询单个学生信息")   # 输出提示信息
    print("=========（c）按性别查询学生信息")   # 输出提示信息
    print("=========（d）按班号查询学生信息")   # 输出提示信息
    x = input("请根据以上序号选择查询类别: ")   # 输入查询的类型
    if x == 'a':   # 如果输入的是a
        num = input("请输入该学生的学号: ")   # 输入要查询的学生的学号
        for s in stu:   # 遍历stu列表中的学生对象
            if s['number'] == num:   # 判断学号是否与输入的学号相同
                show_stu(s)   # 调用show_stu函数显示学生的信息
                return   # 终止函数执行
        print(f"未查询到学号为 {num} 的学生")   # 输出提示信息
    elif x == 'b':   # 如果输入的是b
        name = input("请输入该学生的姓名: ")   # 输入要查询的学生的姓名
        found = False   # 创建一个变量found，并将其值设置为False
        for s in stu:   # 遍历stu列表中的学生对象
            if s['name'] == name:   # 判断姓名是否与输入的姓名相同
                show_stu(s)   # 调用show_stu函数显示学生的信息
                found = True   # 将found的值设置为True
        if not found:   # 如果found的值为False
            print(f"未查询到姓名为 {name} 的学生")   # 输出提示信息
    elif x == 'c':   # 如果输入的是c
        gender = input("请输入要查询学生的性别: ")   # 输入要查询的学生的性别
        for s in stu:   # 遍历stu列表中的学生对象
            if s['gender'] == gender:   # 判断性别是否与输入的性别相同
                show_stu(s)   # 调用show_stu函数显示学生的信息
    elif x == 'd':   # 如果输入的是d
        stu_class = input("请输入要查询学生的班号: ")   # 输入要查询的学生的班号
        for s in stu:   # 遍历stu列表中的学生对象
            if s['stu_class'] == stu_class:   # 判断班号是否与输入的班号相同
                show_stu(s)   # 调用show_stu函数显示学生的信息

def count_info():   # 定义一个名为count_info的函数，用于统计学生信息
    print("=========（a）按性别统计学生人数")   # 输出提示信息
    print("=========（b）按班号统计学生人数")   # 输出提示信息
    print("=========（c）按年龄统计学生人数")   # 输出提示信息
    print("=========（d）按系别统计学生人数")   # 输出提示信息
    x = input("请根据以上序号选择统计类别: ")   # 输入统计的类型
    if x == 'a':   # 如果输入的是a
        gender = input("请输入要统计的学生的性别: ")   # 输入要统计的学生的性别
        count = sum(1 for s in stu if s['gender'] == gender)   # 统计stu列表中性别相同的学生的个数
        print(f"{gender}性学生共有 {count} 个")   # 输出统计结果
    elif x == 'b':   # 如果输入的是b
        stu_class = input("请输入要统计的学生的班号: ")   # 输入要统计的学生的班号
        count = sum(1 for s in stu if s['stu_class'] == stu_class)   # 统计stu列表中班号相同的学生的个数
        print(f"{stu_class}班学生共有 {count} 个")   # 输出统计结果
    elif x == 'c':   # 如果输入的是c
        age = int(input("请输入要统计的学生的年龄: "))   # 输入要统计的学生的年龄
        count = sum(1 for s in stu if s['age'] == age)   # 统计stu列表中年龄相同的学生的个数
        print(f"年龄为 {age} 岁的学生共有 {count} 个")   # 输出统计结果
    elif x == 'd':   # 如果输入的是d
        department = input("请输入要统计的学生的系别: ")   # 输入要统计的学生的系别
        count = sum(1 for s in stu if s['department'] == department)   # 统计stu列表中系别相同的学生的个数
        print(f"{department}的学生共有 {count} 个")   # 输出统计结果

def show_all_students():   # 定义一个名为show_all_students的函数，用于显示所有学生的基本信息
    print("=========所有学生的基本信息如下=========")   # 输出提示信息
    print(f"{'学号':<10}{'姓名':<10}{'性别':<10}{'年龄':<10}{'班号':<10}{'专业':<20}{'系别':<20}")   # 输出表头
    print("-" * 80)   # 输出分隔线
    for s in stu:   # 遍历stu列表中的学生对象
        show_stu(s)   # 调用show_stu函数显示学生的信息

def sort_students():   # 定义一个名为sort_students的函数，用于排序学生信息
    print("=========（a）按学号正序排序学生信息")   # 输出提示信息
    print("=========（b）按学号倒序排序学生信息")   # 输出提示信息
    x = input("请根据以上序号选择排序类别: ")   # 输入排序的类型
    if x == 'a':   # 如果输入的是a
        sorted_stu = sorted(stu, key=lambda s: s['number'])   # 按学号正序排序stu列表中的学生对象
    elif x == 'b':   # 如果输入的是b
        sorted_stu = sorted(stu, key=lambda s: s['number'], reverse=True)   # 按学号倒序排序stu列表中的学生对象
    else:   # 如果输入的不是a和b，则输出提示信息，并返回
        print("无效的选择")
        return

    print("=========排序后的学生信息如下=========")   # 输出提示信息
    print(f"{'学号':<10}{'姓名':<10}{'性别':<10}{'年龄':<10}{'班号':<10}{'专业':<20}{'系别':<20}")   # 输出表头
    print("-" * 80)   # 输出分隔线
    for s in sorted_stu:   # 遍历排序后的学生对象列表
        show_stu(s)   # 调用show_stu函数显示学生的信息

def delete_first_line():   # 定义一个名为delete_first_line的函数，用于删除文件的第一行
    with open("学生学籍信息.txt", "r", encoding='utf-8') as f:   # 使用with语句打开文件
        lines = f.readlines()   # 读取文件的所有行
    with open("学生学籍信息.txt", "w", encoding='utf-8') as f:   # 使用with语句打开文件
        f.writelines(lines[1:])   # 将除第一行外的所有行写入文件

def put_out_file():   # 定义一个名为put_out_file的函数，用于从文件中读取学生信息
    global total   # 声明total为全局变量
    try:   # 使用try-except处理异常
        with open("学生学籍信息.txt", "r", encoding='utf-8') as f:   # 使用with语句打开文件
            for line in f:   # 遍历文件的每一行
                data = line.strip().split()   # 去除行末的换行符，并将行按制表符分割成多个元素
                if len(data) == 7:   # 如果行中包含7个元素
                    student = {
                        "number": data[0],
                        "name": data[1],
                        "gender": data[2],
                        "age": int(data[3]),
                        "stu_class": data[4],
                        "major": data[5],
                        "department": data[6]
                    }
                    stu.append(student)   # 将学生对象添加到stu列表中
                    total += 1   # 增加学生人数
    except FileNotFoundError:   # 如果文件未找到，则输出提示信息
        print("文件打开失败")

def put_in_file():   # 定义一个名为put_in_file的函数，用于将学生信息写入文件
    with open("学生学籍信息.txt", "w", encoding='utf-8') as f:   # 使用with语句打开文件
        f.write("学号\t姓名\t性别\t年龄\t班号\t专业\t系别\n")   # 写入表头
        for s in stu:   # 遍历stu列表中的学生对象
            f.write(f"{s['number']}\t{s['name']}\t{s['gender']}\t{s['age']}\t{s['stu_class']}\t{s['major']}\t{s['department']}\n")   # 写入学生的信息

def main():   # 主函数
    delete_first_line()   # 调用delete_first_line函数删除文件的第一行
    put_out_file()   # 调用put_out_file函数将文件中的学生信息读取到stu列表中

    print("==========================学生学籍管理系统==========================")   # 输出提示信息
    while True:   # 使用无限循环，直到退出系统
        print("\n\n|-------------------------------菜单-------------------------------|")   # 输出菜单
        print("|======================（1）显示全部学生信息=======================|")   # 输出菜单
        print("|======================（2）学生基本信息的录入=====================|")   # 输出菜单
        print("|======================（3）学生基本信息的删除=====================|")   # 输出菜单
        print("|======================（4）学生基本信息的修改=====================|")   # 输出菜单
        print("|======================（5）学生基本信息的查询=====================|")   # 输出菜单
        print("|======================（6）学生基本信息的统计=====================|")   # 输出菜单
        print("|======================（7）按学号排序学生信息=====================|")   # 输出菜单
        print("|======================     （8）退出系统     =====================|")   # 输出菜单
        print("|--|----------------------------------------------------------------")   # 输出菜单
        x = int(input("请根据以上序号选择您要执行的功能: "))   # 输入要执行的功能的序号
        os.system('cls' if os.name == 'nt' else 'clear')   # 调用os.system函数执行清屏操作
        if x == 8:   # 如果输入的是8
            print("***************学生学籍管理系统已退出***************")   # 输出提示信息
            break   # 退出循环，终止程序的执行
        elif x == 1:   # 如果输入的是1
            show_all_students()   # 调用show_all_students函数显示所有学生的信息
            input("已完成“显示全部学生信息”操作，点击回车返回菜单...")   # 输入回车，以进行下一步操作
            os.system('cls' if os.name == 'nt' else 'clear')   # 调用os.system函数执行清屏操作
        elif x == 2:   # 如果输入的是2
            input_info()   # 调用input_info函数录入学生信息
            input("已完成“录入学生信息”操作，点击回车返回菜单...")   # 输入回车，以进行下一步操作
            os.system('cls' if os.name == 'nt' else 'clear')   # 调用os.system函数执行清屏操作
        elif x == 3:   # 如果输入的是3
            delete_info()   # 调用delete_info函数删除学生信息
            input("已完成“删除学生信息”操作，点击回车返回菜单...")   # 输入回车，以进行下一步操作
            os.system('cls' if os.name == 'nt' else 'clear')   # 调用os.system函数执行清屏操作
        elif x == 4:   # 如果输入的是4
            recompose_info()   # 调用recompose_info函数修改学生信息
            input("已完成“修改学生信息”操作，点击回车返回菜单...")   # 输入回车，以进行下一步操作
            os.system('cls' if os.name == 'nt' else 'clear')   # 调用os.system函数执行清屏操作
        elif x == 5:   # 如果输入的是5
            find_info()   # 调用find_info函数查询学生信息
            input("已完成“查询学生信息”操作，点击回车返回菜单...")   # 输入回车，以进行下一步操作
            os.system('cls' if os.name == 'nt' else 'clear')   # 调用os.system函数执行清屏操作
        elif x == 6:   # 如果输入的是6
            count_info()   # 调用count_info函数统计学生信息
            input("已完成“统计学生信息”操作，点击回车返回菜单...")   # 输入回车，以进行下一步操作
            os.system('cls' if os.name == 'nt' else 'clear')   # 调用os.system函数执行清屏操作
        elif x == 7:   # 如果输入的是7
            sort_students()   # 调用sort_students函数排序学生信息
            input("已完成“排序学生信息”操作，点击回车返回菜单...")   # 输入回车，以进行下一步操作
            os.system('cls' if os.name == 'nt' else 'clear')   # 调用os.system函数执行清屏操作

    put_in_file()   # 调用put_in_file函数将学生信息写入文件

if __name__ == "__main__":
    main()   # 调用main函数开始执行程序
